package com.rykj.qxj.rest;

import com.rykj.qxj.server.model.entity.ApiManage;
import com.rykj.qxj.server.model.entity.Apply;
import com.rykj.qxj.server.model.entity.DataMart;
import com.rykj.qxj.server.model.entity.DatabaseSource;
import com.rykj.qxj.server.services.IApiManageService;
import com.rykj.qxj.server.services.IApplyManageService;
import com.rykj.qxj.server.services.IDataMartService;
import com.rykj.qxj.server.services.IDatabaseSourceService;
import com.rykj.qxj.server.util.DES;
import com.rykj.qxj.server.util.HttpClientUtils;
import com.rykj.qxj.server.util.JdbcClient;
import com.rykj.qxj.server.util.date.DateUtils;
import com.rykj.qxj.server.util.object.StringUtils;
import com.rykj.qxj.util.Result;
import com.techindata.cacheredis.CacheGet;
import com.techindata.cacheredis.CacheHash;
import com.techindata.cacheredis.CacheZSet;
import io.swagger.annotations.*;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Tuple;

import java.text.SimpleDateFormat;
import java.util.*;

@Log4j
@RestController
@RequestMapping("/v1/monitor")
@Api(tags="监控管理相关接口服务")
public class MonitorController {
	@Autowired
	private IApiManageService apiManageService;
	@Autowired
	private IDatabaseSourceService databaseSourceService;
	@Autowired
	private IApplyManageService applyManageService;
    final String oracle_url = "jdbc:oracle:thin:@10.153.98.22:1521:SZQX1";
    final String user_name = "szjk";
    final String pass_word = "pwdjk2019";
    final String oracle_driver = "oracle.jdbc.driver.OracleDriver";
	private final   String mysqlDriver = "com.mysql.jdbc.Driver";
	@Autowired
	private IDataMartService dataMartService;

	private static final String ALL_API_VISITCOUNT_PER_MINUTE= "allApiVisitCountPerMinute";
	private static final String PER_API_VISITCOUNT= "perApiVisitCount";
	private static final String PER_APPLICATION_VISITCOUNT= "perApplicationVisitCount";

    @GetMapping("/dataMonitorHomeTotal")
    @ApiOperation(value="管理后台-数据监控首页-数据状态监控接口",notes ="管理后台-数据监控首页-数据状态监控接口")
    public Result dataMonitorHomeTotal(){
        try{
            String sql = "select count(1) as zs,nvl(sum(case when INDEXID like '1%' then 1 end),0) as cj,nvl(sum(case when INDEXID like '1%' and ceil((sysdate-LATESTACTIVETIME)* 24)>6 then 1 end),0) as cjsb," +
                    "nvl(sum(case when INDEXID like '2%' then 1 end),0) as cl,nvl(sum(case when INDEXID like '2%' and ceil((sysdate-LATESTACTIVETIME)* 24)>6 then 1 end),0) as clsb," +
                    "nvl(sum(case when INDEXID like '3%' then 1 end),0) as rk,nvl(sum(case when INDEXID like '3%' and ceil((sysdate-LATESTACTIVETIME)* 24)>6 then 1 end),0) as rksb," +
                    "nvl(sum(case when INDEXID like '5%' then 1 end),0) as cs,nvl(sum(case when INDEXID like '5%' and ceil((sysdate-LATESTACTIVETIME)* 24)>6 then 1 end),0) as cssb," +
                    "nvl(sum(case when INDEXID like '6%' then 1 end),0) as tb,nvl(sum(case when INDEXID like '6%' and ceil((sysdate-LATESTACTIVETIME)* 24)>6 then 1 end),0) as tbsb  from T_PROACTLOG";
            JdbcClient jdbcClient = new JdbcClient(oracle_url,user_name,pass_word,oracle_driver);
            List<Map<String, Object>> list = jdbcClient.query(sql);
            Map monitor = new HashMap();
            for(Map<String,Object> map : list){
                Map dateStatus = new HashMap<>();
                int cjsb = Integer.parseInt( map.get("CJSB").toString());
                if(cjsb>0){
                    dateStatus.put("cjStatus","failed"); //观测数据采集状态
                }else{
                    dateStatus.put("cjStatus","success"); //观测数据采集状态
                }
                int clsb = Integer.parseInt( map.get("CLSB").toString());
                if(clsb>0){
                    dateStatus.put("clStatus","failed"); //观测数据采集状态
                }else{
                    dateStatus.put("clStatus","success"); //观测数据采集状态
                }
                int rksb = Integer.parseInt( map.get("RKSB").toString());
                if(rksb>0){
                    dateStatus.put("rkStatus","failed"); //观测数据采集状态
                }else{
                    dateStatus.put("rkStatus","success"); //观测数据采集状态
                }
                monitor.put("dateStatus",dateStatus);
                Map dataTotal = new HashMap<>();
                dataTotal.put("allTotal",Integer.parseInt( map.get("ZS").toString())); //进程总数
                dataTotal.put("cjTotal",Integer.parseInt( map.get("CJ").toString())); //数据采集入库数量
                dataTotal.put("cjFailedTotal",Integer.parseInt( map.get("CJSB").toString())); //数据采集入库失败数量
                dataTotal.put("clTotal",Integer.parseInt( map.get("CL").toString())); //数据处理数量
                dataTotal.put("clFailedTotal",Integer.parseInt( map.get("CLSB").toString())); //数据处理失败数量
                dataTotal.put("rkTotal",Integer.parseInt( map.get("RK").toString())); //数据入库数量
                dataTotal.put("rkFailedTotal",Integer.parseInt( map.get("RKSB").toString())); //数据入库失败数量
                dataTotal.put("csTotal",Integer.parseInt( map.get("CS").toString())); //数据入库数量
                dataTotal.put("csFailedTotal",Integer.parseInt( map.get("CSSB").toString())); //数据入库失败数量
                dataTotal.put("tbTotal",Integer.parseInt( map.get("TB").toString())); //数据入库数量
                dataTotal.put("tbFailedTotal",Integer.parseInt( map.get("TBSB").toString())); //数据入库失败数量
                monitor.put("dataTotal",dataTotal);
            }

            return new Result( monitor);
        }catch (Exception e){
            log.error("数据查询失败", e);
            return new Result(false, e.getMessage());
        }
    }

    @GetMapping("/dataMonitorHomeStatistics")
    @ApiOperation(value="管理后台-数据监控首页-数据统计接口",notes ="管理后台-数据监控首页-数据统计接口")
    @ApiResponses(value = { @ApiResponse(code = 200, message = "monitorDate：监控时间(HH:mm)，collectTotal：采集数目，" +
            "handleTotal：处理数目，storageTotal：入库数目，collectFailTotal：采集失败数目，" +
            "handleFailTotal：处理失败数目，storageFailTotal：入库失败数目")})
    public Result dataMonitorHomeStatistics(){
        try{
            String sql = "select to_char(sysdate,'hh24')||':'||a.dt dt,nvl(a.cjsl,0) cjsl,nvl(b.clsl,0) clsl,nvl(c.rksl,0) rksl,nvl(d.cssl,0) cssl,nvl(e.tbsl,0) tbsl from (\n" +
                    "select to_char(CRTTIME,'mi') dt,count(1) cjsl from T_COLLECTLOG where CRTTIME > sysdate-10/1440 GROUP BY to_char(CRTTIME,'mi') ) a left join (\n" +
                    "select to_char(CRTTIME,'mi') dt,count(1) clsl from T_PROCESSLOG where CRTTIME > sysdate-10/1440 GROUP BY to_char(CRTTIME,'mi') ) b on a.dt=b.dt left join (\n" +
                    "select to_char(CRTTIME,'mi') dt,sum(1) rksl from T_TODBLOG where CRTTIME > sysdate-10/1440 GROUP BY to_char(CRTTIME,'mi')) c on b.dt=c.dt left join (\n" +
                    "select to_char(CRTTIME,'mi') dt,count(1) cssl from T_TRANSFERLOG where CRTTIME > sysdate-10/1440 GROUP BY to_char(CRTTIME,'mi')) d on c.dt = d.dt left join(\n" +
                    "select to_char(CRTTIME,'mi') dt,count(1) tbsl from T_DBSYNCLOG where CRTTIME > sysdate-10/1440 GROUP BY to_char(CRTTIME,'mi')) e on d.dt = e.dt order by a.dt";
            JdbcClient jdbcClient = new JdbcClient(oracle_url,user_name,pass_word,oracle_driver);
            List list = jdbcClient.query(sql);
            return new Result(list);
        }catch (Exception e){
            log.error("数据查询失败", e);
            return new Result(false, e.getMessage());
        }
    }
    @GetMapping("/applicationMonitorTotal")
    @ApiOperation(value="首页-监控管理-应用监控",notes ="首页-监控管理-应用监控")
    public Result applicationMonitorTotal(){
    	try{
    		//结果Map
    		Map<String,Object> resultMap=new HashMap<String, Object>();
    		//总应用数量
    		Map<String, Object> applicationTotal = applyManageService.applicationTotal();
    		//总接口数量
    		Map<String, Object> apiTotal = apiManageService.apiTotal();
    		//查询所有上线的应用
    		List<Apply> applys = applyManageService.findApplysListByIssuance();
    		List<Map<String,Object>> resultMapList=new ArrayList<Map<String,Object>>();
    		Integer applicationTotalVisit=0;
    		for (Apply apply : applys) {
    			Map<String,Object> itemMap=new HashMap<String, Object>();
    			Integer singleApplyVisitSum =Integer.parseInt(CacheGet.getValue(apply.getApplyKey())==null?"0":CacheGet.getValue(apply.getApplyKey()));
    			itemMap.put(apply.getApplyName(), singleApplyVisitSum);
    			applicationTotalVisit+=singleApplyVisitSum;
    			resultMapList.add(itemMap);
			}
    		resultMap.put("applicationTotal", applicationTotal.get("applyTotal"));
    		resultMap.put("apiTotal", apiTotal.get("apiTotal"));
    		resultMap.put("applicationTotalVisit", applicationTotalVisit);
    		resultMap.put("itemData",resultMapList);
    		return new Result(resultMap);
    	}catch (Exception e){
    		log.error("数据查询失败", e);
    		return new Result(false, e.getMessage());
    	}
    }
    @GetMapping("/applicationMonitorApplyTop10")
    @ApiOperation(value="首页-监控管理-应用监控-应用访问量投票top10",notes ="首页-监控管理-应用监控-应用访问量投票top10")
    public Result applicationMonitorApplyTop10(){
    	try{
    		//结果Map
    		List<Map<String,Object>> resultMap=new ArrayList<Map<String,Object>>();
    		Set<Tuple> zrevrangeWithScores = CacheZSet.zrevrangeWithScores(PER_APPLICATION_VISITCOUNT, 0, 9);
    		for (Tuple tuple : zrevrangeWithScores) {
    			Map<String,Object> itemData=new HashMap<String,Object>();
    			Apply app = applyManageService.selectApplyByAppKey(tuple.getElement());
    			if(app!=null) {
    			itemData.put("name", app.getApplyName());
    			DataMart dataMart = dataMartService.selectDataMart(app.getCategoryId());
    			if(null!=dataMart) {
    				itemData.put("type", dataMart.getMartName()+"->"+app.getApplyName()); //需要修改代码
    			}

    			itemData.put("createTime", app.getCreatedTime());
    			itemData.put("count", tuple.getScore());//应用访问次数
    			resultMap.add(itemData);
    			}
			}
    		//自定义按照访问量倒序排序
    		Collections.sort(resultMap, new Comparator<Map<String,Object>>(){
				@Override
				public int compare(Map<String, Object> o1, Map<String, Object> o2) {
					int temp=Double.valueOf(o1.get("count").toString())>Double.valueOf(o2.get("count").toString())?-1:0;
					return temp;
				}
    		});
    		return new Result(resultMap);
    	}catch (Exception e){
    		log.error("数据查询失败", e);
    		return new Result(false, e.getMessage());
    	}
    }
    @GetMapping("/applicationMonitorApiTop10")
    @ApiOperation(value="首页-监控管理-应用监控-接口访问量top10",notes ="首页-监控管理-应用监控-接口访问量top10")
    public Result applicationMonitorApiTop10(){
    	try{
    		//结果Map
    		List<Map<String,Object>> resultMap=new ArrayList<Map<String,Object>>();
    		Set<Tuple> zrevrangeWithScores = CacheZSet.zrevrangeWithScores(PER_API_VISITCOUNT, 0, 9);
    		for (Tuple tuple : zrevrangeWithScores) {
    			Map<String,Object> itemData=new HashMap<String,Object>();
    			StringBuffer sb=new StringBuffer();
    			sb.append("/").append(tuple.getElement());
    			log.info("每个API访问量成员==="+sb.toString().replaceAll(":", "/"));
    			ApiManage api = apiManageService.selectApiManageByUrl(sb.toString().replaceAll(":", "/"));
    			itemData.put("name", api.getName());
    			DataMart dataMart = dataMartService.selectDataMart(api.getApiTypeId());
    			if(null!=dataMart) {
    				itemData.put("type", dataMart.getMartName()+"->"+api.getName());
    			}
    			itemData.put("createTime",api.getCreateTime());
    			itemData.put("count", tuple.getScore());//接口访问次数
    			resultMap.add(itemData);
			}
    		//自定义按照访问量倒序排序
    	/*	Collections.sort(resultMap, new Comparator<Map<String,Object>>(){
				@Override
				public int compare(Map<String, Object> o1, Map<String, Object> o2) {
					int temp=Double.valueOf(o1.get("count").toString())>Double.valueOf(o2.get("count").toString())?-1:0;
					return temp;
				}
    			
    		});*/
    		return new Result(resultMap);
    	}catch (Exception e){
    		log.error("数据查询失败", e);
    		return new Result(false, e.getMessage());
    	}
    }
    @GetMapping("/allApiVisitCountPerMinute")
    @ApiOperation(value="首页-监控管理-应用监控-所有接口每分钟访问量",notes ="首页-监控管理-应用监控-所有接口每分钟访问量")
    public Result allApiVisitCountPerMinute(){
    	try{
    		//结果Map
    		List<Map<String,String>> resultMap=new ArrayList<Map<String,String>>();
    		SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    		Map<String,String> map=new HashMap<>();
    		Date nowdate = new Date();
			String addHowMinute="";
			String value="";
			for(int i=60;i>=0;i--) {
				addHowMinute = sdf3.format(DateUtils.addHowMinute(nowdate, -i));
				value = CacheGet.getValue(addHowMinute);
				Map<String,String> temp=new HashMap<String,String>();
				temp.put("time", addHowMinute.substring(11));
				temp.put("value", StringUtils.isEmpty(value)?"0":value);
				resultMap.add(temp);
    		}
    		/*List<Map.Entry<String, String>> mapInfo=new ArrayList<Map.Entry<String,String>>(map.entrySet());
    		Collections.sort(mapInfo, new Comparator<Map.Entry<String, String>>(){
    			@Override
    			public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
    				return o1.getKey().toString().compareTo(o2.getKey().toString());
    			}
    		});*/
    		Map<String, String> hgetAllMap = CacheHash.hgetAll(ALL_API_VISITCOUNT_PER_MINUTE);
    		//if(hgetAllMap!=null) {
    			//Set<String> key = hgetAllMap.keySet();
    		//	for (Entry<String, String> entry : mapInfo) {
    				//for (String keyStr : key) {
    				//	if(keyStr.equals(entry.getKey())) {
    				//		entry.setValue(hgetAllMap.get(keyStr));
    					//}
					//}
   			//     }
    			
    		//}
//    		for (Entry<String, String> entry : mapInfo) {
//				Map<String,String> temp=new HashMap<String,String>();
//				temp.put("time", entry.getKey().substring(11));
//				temp.put("value", entry.getValue());
//				resultMap.add(temp);
//			}
    		/*Set<String> keySet = hgetAll.keySet();
    		for (String key : keySet) {
    			Map<String,String> item=new HashMap<String,String>();
    			item.put("time", key);
    			item.put("value", hgetAll.get(key));
    			resultMap.add(item);
			}*/
    		return new Result(resultMap);
    	}catch (Exception e){
    		log.error("数据查询失败", e);
    		return new Result(false, e.getMessage());
    	}
    }

	@GetMapping("/getFullviewList")
	@ApiOperation(value="分页获取告警事件列表",notes ="分页获取告警事件列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "currentPage", value = "当前页数",required = true,paramType = "query"),
			@ApiImplicitParam(name = "pageSize", value = "显示行数",required = true,paramType = "query"),
			@ApiImplicitParam(name = "status", value = "状态",paramType = "query"),
			@ApiImplicitParam(name = "timeStart", value = "开始时间",paramType = "query"),
			@ApiImplicitParam(name = "timeEnd", value = "结束时间",paramType = "query")
	})
	public Result getDatabaseSourceList(@RequestParam(value = "currentPage") Integer currentPage,
										@RequestParam(value = "pageSize") Integer pageSize,
										@RequestParam(value = "status",required = false) String status,
										@RequestParam(value = "timeStart",required = false) String timeStart,
										@RequestParam(value = "timeEnd",required = false) String timeEnd){
		try{
			Long currentTime = System.currentTimeMillis();
			log.info("====currentTime==="+currentTime);
			String url ="http://cn-shenzhen-szqx-d01-plat-monitor.aso.ops.szqx.com:8092/aso/fullview/event/list?service=&region=&level=&product=";
			if(StringUtils.isNotEmpty(status)){
				url +="&status="+status;
			}
			if(StringUtils.isNotEmpty(timeStart)){
				if(currentTime<Long.parseLong(timeStart)){
					return new Result(false, "开始时间不能大于当前系统时间");
				}
				url +="&timeStart="+timeStart;
			}
			if(StringUtils.isNotEmpty(timeEnd)){
				if(currentTime<Long.parseLong(timeEnd)){
					return new Result(false, "截止时间不能大于当前系统时间");
				}
				url +="&timeEnd="+timeEnd;
			}
			url +="&currentPage="+currentPage;
			url +="&pageSize="+pageSize;

			String retStr=HttpClientUtils.get(url);
			log.info("====告警事件===="+retStr);
			return new Result(retStr);
		}catch (Exception e){
			log.error("查询失败", e);
			return new Result(false, "查询失败");
		}
	}

	@GetMapping("/platformCount")
	@ApiOperation(value="数据接口平台数据分类,数据量,系统接入数量,接口访问总量统计",notes ="数据接口平台数据分类,数据量,系统接入数量,接口访问总量统计")
	public Result getDataInterfacePlatformCount(){
		Map<String,Object> resultMap = new HashMap<>();
		try{
			List<Map<String,Object>> dataClassCounts= new ArrayList<>();
			List<Map<String,Object>> marts =dataMartService.getMartBasicCount();
			DatabaseSource databaseSource = databaseSourceService.getSzqxReadDataSource();
			String sql =" select table_name  tableName ,table_rows tableRows, round((data_length/1024/1024),2)  dataSize  from information_schema.tables  " +
					"where  data_length>0 and table_schema='szqx'";
			String databaseUrl = "jdbc:mysql://"+databaseSource.getDatabaseIP()+":"+databaseSource.getPort()+"/"+databaseSource.getDatabaseName()+ "?useUnicode=true&characterEncoding=utf-8";
			String password = databaseSource.getPassword().replaceAll("%2B","+");
			password=new DES().decode(password);
			JdbcClient jdbcClient = new JdbcClient(databaseUrl,databaseSource.getUserName(),password,mysqlDriver);
			List<Map<String, Object>> tableList = jdbcClient.query(sql);
			String tableNams = "";
			//DecimalFormat df = new DecimalFormat("0.00");
			for (Map<String,Object> mart: marts) {
				int dataAmount =0;
				//double dataSize=0.0;
				Map<String,Object> classData=new HashMap<>();
				classData.put("className",mart.get("className"));
				classData.put("classBasicCount",mart.get("classBasicCount"));
				tableNams = (mart.get("tableNames")+"").toLowerCase();
				for (Map<String,Object>  table:tableList ) {
                    if(tableNams.contains((table.get("tableName")+"").toLowerCase())){
						dataAmount+=Integer.valueOf(table.get("tableRows")+"");
						//dataSize+=Double.valueOf(table.get("dataSize")+"");
					}
				}
				classData.put("dataAmount",dataAmount);
			//	classData.put("dataSize",Double.valueOf(df.format(dataSize)));
				dataClassCounts.add(classData);
			}
			resultMap.put("dataClassCount",dataClassCounts);
		    Integer applyTotal=	applyManageService.getAppTotal();
			resultMap.put("applyTotal",applyTotal);
			String value = CacheGet.getValue("apiTotalvisitCount");
			if(StringUtils.isBlank(value)) {
				resultMap.put("apiVisitTotal",0);
			}else {
				resultMap.put("apiVisitTotal",Integer.valueOf(value));
			}
		}catch (Exception e){
				log.error("统计失败", e);
				return new Result(false, "统计失败");
		}

		return new Result(resultMap);
	}




    public static void main(String[] args) {
        System.out.println(DateUtils.getDate(DateUtils.addHowMinute(new Date(),1),"HH:mm"));
    }
}
